home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume24 / mkid2 / part02 < prev    next >
Encoding:
Internet Message Format  |  1991-10-09  |  38.1 KB

  1. Subject:  v24i090:  Program identifier database tools, Part02/07
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: 271ee6f4 2c512db7 ccab2514 8e78d072
  5.  
  6. Submitted-by: Tom Horsley <tom@hcx2.ssd.csd.harris.com>
  7. Posting-number: Volume 24, Issue 90
  8. Archive-name: mkid2/part02
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 2 (of 7)."
  17. # Contents:  cannoname.c iid.1 iid.help mkid.1 paths.c scan-text.c
  18. #   symfunc.el unsymlink.c
  19. # Wrapped by tom@hcx2 on Tue Feb 26 10:03:02 1991
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. if test -f 'cannoname.c' -a "${1}" != "-c" ; then 
  22.   echo shar: Will not clobber existing file \"'cannoname.c'\"
  23. else
  24. echo shar: Extracting \"'cannoname.c'\" \(4112 characters\)
  25. sed "s/^X//" >'cannoname.c' <<'END_OF_FILE'
  26. X/* This file contains routines which put a file name into cannonical
  27. X * form.
  28. X */
  29. X
  30. X#define NULL 0
  31. X
  32. X/* define special name components */
  33. X
  34. Xstatic char slash[]  = "/" ;
  35. Xstatic char dot[]    = "." ;
  36. Xstatic char dotdot[] = ".." ;
  37. X
  38. X/* nextc points to the next character to look at in the string or is
  39. X * null if the end of string was reached.
  40. X *
  41. X * namep points to buffer that holds the components.
  42. X */
  43. Xstatic char * nextc = NULL ;
  44. Xstatic char * namep ;
  45. X
  46. X/* lexname - Return next name component. Uses global variables initialized
  47. X * by cannoname to figure out what it is scanning.
  48. X */
  49. Xstatic char *
  50. Xlexname()
  51. X{
  52. X   char   c ;
  53. X   char * d ;
  54. X
  55. X   if (nextc) {
  56. X      c = *nextc++ ;
  57. X      if (c == '\0') {
  58. X         nextc = NULL ;
  59. X         return(NULL) ;
  60. X      }
  61. X      if (c == '/') {
  62. X         return(&slash[0]) ;
  63. X      }
  64. X      if (c == '.') {
  65. X         if ((*nextc == '/') || (*nextc == '\0')) return(&dot[0]) ;
  66. X         if (*nextc == '.' && (*(nextc+1) == '/' || *(nextc+1) == '\0')) {
  67. X            ++nextc ;
  68. X            return(&dotdot[0]) ;
  69. X         }
  70. X      }
  71. X      d = namep;
  72. X      *namep++ = c;
  73. X      while ((c = *nextc) != '/') {
  74. X         *namep++ = c ;
  75. X         if (c == '\0') {
  76. X            nextc = NULL ;
  77. X            return(d) ;
  78. X         }
  79. X         ++nextc;
  80. X      }
  81. X      *namep++ = '\0' ;
  82. X      return(d) ;
  83. X   } else {
  84. X      return(NULL) ;
  85. X   }
  86. X}
  87. X
  88. X/* cannoname - Put a file name in cannonical form. Looks for all the
  89. X * whacky wonderful things a demented *ni* programmer might put
  90. X * in a file name and reduces the name to cannonical form.
  91. X */
  92. Xvoid
  93. Xcannoname(n)
  94. X   char * n;
  95. X{
  96. X   char *  components[1024] ;
  97. X   char ** cap = &components[0] ;
  98. X   char ** cad ;
  99. X   char *  cp ;
  100. X   char    namebuf[2048] ;
  101. X   char *  s ;
  102. X
  103. X   /* initialize scanner */
  104. X   nextc = n ;
  105. X   namep = &namebuf[0] ;
  106. X
  107. X   /* break the file name into individual components */
  108. X   while ((cp = lexname()) != NULL) {
  109. X      *cap++ = cp ;
  110. X   }
  111. X
  112. X   /* If name is empty, leave it that way */
  113. X   if (cap == &components[0]) return ;
  114. X
  115. X   /* flag end of component list */
  116. X   *cap = NULL ;
  117. X
  118. X   /* remove all trailing slashes and dots */
  119. X   while ((--cap != &components[0]) &&
  120. X          ((*cap == &slash[0]) || (*cap == &dot[0]))) *cap = NULL ;
  121. X
  122. X   /* squeeze out all . / component sequences */
  123. X   cap = &components[0] ;
  124. X   cad = cap ;
  125. X   while (*cap != NULL) {
  126. X      if ((*cap == &dot[0]) && (*(cap+1) == &slash[0])) {
  127. X         cap += 2;
  128. X      } else {
  129. X         *cad++ = *cap++ ;
  130. X      }
  131. X   }
  132. X   *cad++ = NULL ;
  133. X
  134. X   /* find multiple // and use last slash as root, except on apollo which
  135. X    * apparently actually uses // in real file names (don't ask me why).
  136. X    */
  137. X#ifndef apollo
  138. X   s = NULL ;
  139. X   cap = &components[0] ;
  140. X   cad = cap ;
  141. X   while (*cap != NULL) {
  142. X      if ((s == &slash[0]) && (*cap == &slash[0])) {
  143. X         cad = &components[0];
  144. X      }
  145. X      s = *cap++;
  146. X      *cad++ = s;
  147. X   }
  148. X   *cad = NULL ;
  149. X#endif
  150. X
  151. X   /* if this is absolute name get rid of any /.. at beginning */
  152. X   if ((components[0] == &slash[0]) && (components[1] == &dotdot[0])) {
  153. X      cap = &components[1] ;
  154. X      cad = cap ;
  155. X      while (*cap == &dotdot[0]) {
  156. X         ++cap;
  157. X         if (*cap == NULL) break ;
  158. X         if (*cap == &slash[0]) ++cap ;
  159. X      }
  160. X      while (*cap != NULL) {
  161. X         *cad++ = *cap++ ;
  162. X      }
  163. X      *cad = NULL ;
  164. X   }
  165. X
  166. X   /* squeeze out any name/.. sequences (but leave leading ../..) */
  167. X   cap = &components[0] ;
  168. X   cad = cap ;
  169. X   while (*cap != NULL) {
  170. X      if ((*cap == &dotdot[0]) &&
  171. X          ((cad-2) >= &components[0]) &&
  172. X          ((*(cad-2)) != &dotdot[0])) {
  173. X         cad -= 2 ;
  174. X         ++cap;
  175. X         if (*cap != NULL) ++cap;
  176. X      } else {
  177. X         *cad++ = *cap++ ;
  178. X      }
  179. X   }
  180. X   /* squeezing out a trailing /.. can leave unsightly trailing /s */
  181. X   if ((cad >= &components[2]) && ((*(cad-1)) == &slash[0])) --cad ;
  182. X   *cad = NULL ;
  183. X   /* if it was just name/.. it now becomes . */
  184. X   if (components[0] == NULL) {
  185. X      components[0] = &dot[0] ;
  186. X      components[1] = NULL ;
  187. X   }
  188. X
  189. X   /* re-assemble components */
  190. X   cap = &components[0] ;
  191. X   while ((s = *cap++) != NULL) {
  192. X      while (*s != NULL) *n++ = *s++;
  193. X   }
  194. X   *n++ = '\0' ;
  195. X}
  196. END_OF_FILE
  197. if test 4112 -ne `wc -c <'cannoname.c'`; then
  198.     echo shar: \"'cannoname.c'\" unpacked with wrong size!
  199. fi
  200. # end of 'cannoname.c'
  201. fi
  202. if test -f 'iid.1' -a "${1}" != "-c" ; then 
  203.   echo shar: Will not clobber existing file \"'iid.1'\"
  204. else
  205. echo shar: Extracting \"'iid.1'\" \(5306 characters\)
  206. sed "s/^X//" >'iid.1' <<'END_OF_FILE'
  207. X.TH IID 1
  208. X.SH NAME
  209. Xiid \- interactive query for ID database
  210. X.SH SYNOPSIS
  211. X.PP
  212. X.B iid
  213. X.RB [ \-a]
  214. X.RB [ \-c \^command]
  215. X.RB [ \-H]
  216. X.SH DESCRIPTION
  217. XThis command provides an interactive query interface to the
  218. X.I ID
  219. Xdatabase.
  220. X.I Iid\^
  221. Xallows you to query an
  222. X.I ID
  223. Xdatabase in a fashion similar to using \fIDIALOG\fP. Any individual
  224. Xquery command results in a list of files that satisfy that query,
  225. Xeach set of files is retained by
  226. X.I iid
  227. Xand assigned a set number. The sets may be combined with
  228. X.IR AND ,
  229. X.I OR
  230. Xand
  231. X.I NOT
  232. Xoperators to produce additional sets. The primitive operators that
  233. Xproduce sets are invocations of the
  234. X.I lid
  235. Xor
  236. X.I aid
  237. Xprograms.
  238. X.SH OPTIONS
  239. XNormally
  240. X.I iid
  241. Xruns interactively. Options may be used to run it in batch mode.
  242. X.TP 8
  243. X.B \-a
  244. XUse the
  245. X.I aid
  246. Xprogram as the default query program, normally
  247. X.I lid
  248. Xis used.
  249. X.TP 8
  250. X.B \-c
  251. XAccept a single command as an argument, run that command, and exit
  252. X.IR Iid .
  253. X.TP
  254. X.B \-H
  255. XPrint a brief help message and exit.
  256. X.SH SUBCOMMANDS
  257. XThe subcommands are used to carry on a dialog with
  258. X.I iid
  259. Xafter invoking the program.
  260. X.PP
  261. XTwo basic query commands are available:
  262. X.B SS
  263. Xand
  264. X.BR FILES .
  265. XThe
  266. X.B SS
  267. Xcommand shows the sets generated by a query, but does not display
  268. Xthe actual file names that satisfy the query.
  269. XThe
  270. X.B FILES
  271. Xcommand only displays the list of files, it does not show any
  272. Xof the sets created during the query.
  273. X.PP
  274. XQueries consist of keywords and identifier strings. The keywords are:
  275. X.B and or not lid aid match
  276. Xand
  277. X.B s<number>
  278. Xwhere
  279. X.B s<number>
  280. Xis a set number consisting of the letter
  281. X.B s
  282. Xfollowed (with no space) by a decimal set number.
  283. XA clause of the form
  284. X.B lid <identifier list>
  285. Xinvokes
  286. X.I lid
  287. Xwith the
  288. X.B <identifier list>
  289. Xas arguments and produces a set of files as a result.
  290. XSubstituting
  291. X.B aid
  292. Xfor
  293. X.B lid
  294. Xruns the
  295. X.I aid
  296. Xprogram to generate the list of files.
  297. XAs a shorthand notation for
  298. X.B lid <identifier>
  299. Xyou may simply use
  300. X.B <identifier>.
  301. XThe
  302. X.B match
  303. Xoperator runs the standard system
  304. X.I ls
  305. Xutility to produce a set of files. This allows sets to be
  306. Xconstructed based on the names of files (using wild cards)
  307. Xrather than contents.
  308. XThe
  309. X.B and or
  310. Xand
  311. X.B not
  312. Xoperators can be used to combine sets in the obvious fashion.
  313. XIf you need to pass any of the keywords as actual arguments to
  314. Xprograms, or if the search strings contain any shell escape
  315. Xcharacters place the argument in quotes.
  316. X.PP
  317. XThe
  318. X.B NOT
  319. Xoperator has highest precedence, followed by
  320. X.B AND
  321. Xand
  322. X.B OR
  323. Xin that order. Parenthesis may be used for grouping.
  324. X.PP
  325. XThe remaining commands are:
  326. X.PP
  327. X.B BEGIN <directory>
  328. Xaccepts a directory name and switches to that directory. By changing
  329. Xdirectories you control which
  330. X.I ID
  331. Xdatabase is searched. Changing directories automatically deletes
  332. Xall the sets constructed so far. The
  333. X.B BEGIN
  334. Xcommand may be abbreviated as
  335. X.BR B .
  336. X.PP
  337. X.B SETS
  338. Xshows the description of all the sets created so far. Each set
  339. Xdescription has the set number, the number of files in the set,
  340. Xand a symbolic description of the query that created the set.
  341. X.PP
  342. X.B SHOW <set number>
  343. Xruns a pager program, passing as arguments all the files in
  344. Xthe specified set. The pager program comes from the
  345. X.B $PAGER
  346. Xenvironment variable. This command may be abbreviated
  347. X.BR P .
  348. X.PP
  349. X.B HELP
  350. Xruns the pager on the help file. The commands
  351. X.B H
  352. Xand
  353. X.B ?
  354. Xalso act as help commands.
  355. X.PP
  356. X.B OFF
  357. Xexits the program.
  358. X.B Q
  359. Xis short for
  360. X.BR OFF .
  361. X.PP
  362. XAll commands and keywords are case insensitive, so that
  363. X.B SHOW ShOW
  364. Xand
  365. X.B show
  366. Xall work equally well.
  367. X.SH INTERFACE
  368. XTwo forms of commands are provided for interface with arbitrary
  369. Xprograms. Any command that is not recognized as one
  370. Xof the above built in
  371. X.I iid
  372. Xcommands, is assumed to be a program which, when run, will print
  373. Xa list of file names.
  374. X.I Iid
  375. Xruns the command as typed, and records the output as a new set
  376. Xwhich may be combined with other sets in subsequent queries.
  377. X.PP
  378. XIf the command starts with a
  379. X.BR !,
  380. X.I iid
  381. Xstrips off the leading
  382. X.B !
  383. Xand simply runs the command. Any output goes to stdout and
  384. Xis not recorded as a set.
  385. X.PP
  386. XIn both types of shell commands, any set numbers specified as
  387. Xarguments are expanded into a list of file names before running
  388. Xthe command.
  389. X.SH EXAMPLE
  390. X.nf
  391. X.ft L
  392. X===> iid
  393. Xiid> ss lid "^get" or lid "Arg$"
  394. X   S0     14  lid -kmn "^get"
  395. X   S1      3  lid -kmn "Arg$"
  396. X   S2     15  (lid -kmn "^get") OR (lid -kmn "Arg$")
  397. Xiid> f s1
  398. Xlid.c
  399. Xpaths.c
  400. Xinit.c
  401. Xiid> off
  402. X.FT P
  403. X.fi
  404. X.EX off
  405. X.PP
  406. XIn this example the
  407. X.B ss
  408. Xcommand displays the sets it creates as it
  409. Xdoes the parts of the query. In this case 3 sets are created, set S0
  410. Xhas 14 files in it, set S1 has 3 files and the union of the two sets,
  411. XS2, has 15 files. A description of the query that created any given
  412. Xset is kept along with the set and displayed when sets are printed.
  413. X.PP
  414. XThe
  415. X.B f s1
  416. Xcommand lists the three files in set S1.
  417. X.PP
  418. XThe 
  419. X.B off
  420. Xcommand terminates the example session.
  421. X.SH HINTS
  422. XThe shell interface commands can be used to generate file sets by
  423. Xrunning the
  424. X.I find
  425. Xor
  426. X.I ls
  427. Xutilities, or compiles of a selected group of files can be done
  428. Xusing the
  429. X.BR ! cc
  430. Xcommand with a set number as the argument.
  431. X.BR ! lp
  432. Xcan be used to print a selected group of files.
  433. X.PP
  434. XThis program interfaces nicely with
  435. X.I emacs
  436. Xif you run the server program and specify the client program
  437. Xas your $PAGER.
  438. X.SH SEE ALSO
  439. Xmkid(1),
  440. Xlid(1),
  441. Xaid(1).
  442. END_OF_FILE
  443. if test 5306 -ne `wc -c <'iid.1'`; then
  444.     echo shar: \"'iid.1'\" unpacked with wrong size!
  445. fi
  446. # end of 'iid.1'
  447. fi
  448. if test -f 'iid.help' -a "${1}" != "-c" ; then 
  449.   echo shar: Will not clobber existing file \"'iid.help'\"
  450. else
  451. echo shar: Extracting \"'iid.help'\" \(3455 characters\)
  452. sed "s/^X//" >'iid.help' <<'END_OF_FILE'
  453. XThe iid program is an interactive shell on  top of the  mkid, lid, aid
  454. Xdatabase programs. It allows interactive queries of  an ID database in
  455. Xa fashion similar to a DIALOG session. Iid remembers the sets of files
  456. Xthat were reported by any  lid or aid request.  These sets are refered
  457. Xto by set numbers. The commands available are:
  458. X
  459. XBEGIN <directory>    cd to directory (presumably containing an ID file).
  460. XB                    short for BEGIN
  461. XSS <query>           run query displaying the sets generated
  462. XFILES <query>        run query listing the files in the final set
  463. XF                    short for FILES
  464. XSHOW <set number>    run pager program on files in set
  465. XP                    short for SHOW
  466. XSETS                 show currently defined sets
  467. XHELP                 run pager on this file
  468. X? or H               short commands for HELP
  469. XOFF                  exit iid
  470. X<cmd>                run a shell command as a file name query
  471. X!<cmd>               run a shell command
  472. X
  473. XA <set number> is the letter 's' (or 'S')  followed (with no space) by
  474. Xa number. Set numbers may be used as terms in a query.
  475. X
  476. XA <query> is:
  477. X   <set number>
  478. X   <identifier>
  479. X   lid <identifier list>
  480. X   aid <identifier list>
  481. X   match <wild card list>
  482. X   <query> or <query>
  483. X   <query> and <query>
  484. X
  485. XThe words  "lid", "aid", "match",  "or", and "and" are keywords, along
  486. Xwith any word that looks like a set number. If you  have to use one of
  487. Xthese (or in arguments to lid, aid  or match, shell escape characters)
  488. Xthen quote the name.
  489. X
  490. XThe  "match" operator constructs a set  of  files by running the "pid"
  491. Xprogram with the wild card  pattern as  an argument. This  is the only
  492. Xoperator    which constructs sets   based  on file  names rather  than
  493. Xcontents.
  494. X
  495. XAn identifier by itself is  simply shorthand for "lid identifier". (If
  496. Xthe -a  option was used  to invoke iid,  then  a simple  identifier is
  497. Xshorthand for "aid identifier").
  498. X
  499. XExample run:
  500. X
  501. X===> iid
  502. X===> ss lid "^get" or lid "Arg$"
  503. X   S0     14  lid -kmn "^get"
  504. X   S1      3  lid -kmn "Arg$"
  505. X   S2     15  (lid -kmn "^get") OR (lid -kmn "Arg$")
  506. X===> f s1
  507. Xlid.c
  508. Xpaths.c
  509. Xinit.c
  510. X===> ls *.c
  511. X   S3     28  ls *.c
  512. X===> ls s*
  513. X   S4      9  ls s*
  514. X===> ss s3 and s4
  515. X   S5      4  (ls *.c) AND (ls s*)
  516. X===> !grep vhil s5
  517. Xscan-c.c:                setCArgs("vhil",'+',"v");
  518. Xscan-c.c:            setCArgs("vhil",'+',"v");
  519. X===> off
  520. X
  521. XIn  this example  the 'ss' command  displays  the sets it creats as it
  522. Xdoes the parts of the  query. In this case  3 sets are created, set S0
  523. Xhas 14 files in it, set S1 has 3 files and the  union of the two sets,
  524. XS2, has 15 files.  A description of the  query that created any  given
  525. Xset is kept along with the set and displayed when sets are printed.
  526. X
  527. XThe 'f s1' command says list the files in set S1, and  the three files
  528. Xin the set are displayed.
  529. X
  530. XThe 'ls'  commands are examples of using  arbitrary  shell commands to
  531. Xgenerate lists  of files. In  this case the  'ls' command. (This could
  532. Xhave been done as part of another query using the 'match' operator).
  533. X
  534. XThe '!grep vhil s5' command runs  the 'grep'  shell command passing as
  535. Xarguments 'vhil' and the names of all the files in s5.
  536. X
  537. XThe 'off' command terminated the example session.
  538. X
  539. XKeywords, commands, and set numbers are recognized  regardless of case
  540. X(and is And is aNd). Other parameters are case sensitive.
  541. X
  542. XThe iid program can  also be run in a  batch mode using the -c option.
  543. XFor more information on command line options, run "iid -H", or use the
  544. XUnix 'man' command.
  545. END_OF_FILE
  546. if test 3455 -ne `wc -c <'iid.help'`; then
  547.     echo shar: \"'iid.help'\" unpacked with wrong size!
  548. fi
  549. # end of 'iid.help'
  550. fi
  551. if test -f 'mkid.1' -a "${1}" != "-c" ; then 
  552.   echo shar: Will not clobber existing file \"'mkid.1'\"
  553. else
  554. echo shar: Extracting \"'mkid.1'\" \(5564 characters\)
  555. sed "s/^X//" >'mkid.1' <<'END_OF_FILE'
  556. X.TH MKID 1
  557. X.SH NAME
  558. Xmkid \- make an id database
  559. X.SH SYNOPSIS
  560. X.B mkid
  561. X.RB [ \-v ]
  562. X.RB [ \-f \^out-file]
  563. X.RB [ \-s \^directory]
  564. X.RB [ \-r \^directory]
  565. X.RB [ \-S \^scanarg]
  566. X.RB [ \-a \^arg-file]
  567. X.RB [ \- ]
  568. X.RB [ \-u ]
  569. X.RB [ files... ]
  570. X.SH DESCRIPTION
  571. X.I Mkid\^
  572. Xbuilds a database that stores numbers and identifier names, as well
  573. Xas the names of the files in which they occur.
  574. X.I Mkid\^
  575. Xis particularly useful with large programs spread out across multiple
  576. Xsource files.  It serves as an aid for program maintenance and as a
  577. X.I guide\^
  578. Xfor perusing a program.
  579. X.PP
  580. XThe following options are recognized:
  581. X.TP 10
  582. X.B \-v
  583. XVerbose.
  584. XReport
  585. X.IR mkid 's
  586. Xprogress in building the database.  The output comes on standard error.
  587. X.TP 10
  588. X.BI \-f out-file\^
  589. XWrite the finished database into
  590. X.IR out-file .
  591. X.B ID\^
  592. Xis the default.
  593. XNormally the names of the files scanned are written to the database
  594. Xas specified in the argument list. If the database sepcified with
  595. X.B \-f
  596. Xis not located in the current directory, then the file names are
  597. Xadjusted so that they are relative to the directory that the
  598. Xdatabase is located in.
  599. X.TP 10
  600. X.BI \-s directory\^
  601. X.TP 10
  602. X.BI \-r directory\^
  603. XIf
  604. X.IR mkid 's
  605. Xattempt to open a source-file fails, it will try to checkout the
  606. Xcorresponding SCCS or RCS file if present.  The
  607. X.B \-s
  608. Xoption tells
  609. X.I mkid\^
  610. Xwhich directory holds the SCCS file.
  611. XSimilarly, the
  612. X.B \-r
  613. Xoption tells
  614. X.I mkid\^
  615. Xwhich directory holds the RCS file.
  616. XIf neither the RCS or SCCS directories are specified,
  617. X.I mkid\^
  618. Xwill first look for an SCCS file in the current directory, then in
  619. X.BI sccs ,
  620. Xand finally in
  621. X.BI SCCS .
  622. XIt will then look for an RCS file in the current directory, and finally in
  623. X.BI RCS .
  624. X.TP 10
  625. X.BI \-a arg-file\^
  626. XOpen and read
  627. X.I arg-file\^
  628. Xin order to obtain a list of source file arguments.  Source file names
  629. Xmust appear one to a line.
  630. X.BI \-S ,
  631. X.BI \-r ,
  632. Xand
  633. X.BI \-s
  634. Xarguments may also be placed one per line in
  635. X.IR file .
  636. XThey are distinguished from source file names by their leading `-'.  If a file name begins
  637. Xwith `-', it can be distinguished from an argument by explicitly prepending the current
  638. Xdirectory string: `./'.
  639. X.TP 10
  640. X.B \-
  641. XThis operates in the same manner as the
  642. X.B \-a
  643. Xoption described above, but reads from the standard input instead of a file.
  644. X.TP 10
  645. X.B \-u
  646. XUpdate an existing database.  Only those files that have been modified
  647. Xsince the database was built will be rescanned.  This is a significant
  648. Xtime-saver for updating large databases where few sources have changed.
  649. X.TP 10
  650. X.B files...
  651. XIf neither the
  652. X.BI \-a ,
  653. X.BI \- ,
  654. Xnor
  655. X.BI \-u ,
  656. Xarguments have been specified, take file names from the command line.
  657. X.TP 10
  658. X.BI \-S scanarg\^
  659. X.I Mkid\^
  660. Xscans source files in order to obtain numbers and identifier names.
  661. XSince the lexical rules of languages differ,
  662. X.I mkid\^
  663. Xapplies a different scanning function to each language in order
  664. Xto conform to that language's lexical rules.
  665. X.I Mkid\^
  666. Xdetermines the source file's language by examining its filename
  667. Xsuffix which commonly occurs after a dot (`.').
  668. XThe
  669. X.B \-S
  670. Xargument is a way of passing language specific arguments to the
  671. Xscanner for that language.  This argument takes a number of forms:
  672. X.br
  673. X-S<suffix>=<language>
  674. X.br
  675. X-S<language>-<arg>
  676. X.br
  677. X+S-<arg>
  678. X.br
  679. X-S<lang>/<lang>/<filter>
  680. X.br
  681. XThe first form associates a suffix with a language.
  682. XFor example -S.c=vhil would cause all .c files to be scanned
  683. Xas though they were language vhil rather than c.
  684. XYou may find
  685. Xout which suffixes are defined for which languages with the following
  686. Xoptions: `-S<suffix>=?' tells which language is bound to
  687. X.IR <suffix> ,
  688. X`-S?=<language>' tells which suffixes are bound to 
  689. X.IR <language> ,
  690. Xand `-S?=?' reports all bindings between suffixes and languages.
  691. X.PP
  692. XThe second form passes an argument for processing by the scanner
  693. Xfor a specific language.  The third form passes an argument to
  694. Xall scanners.
  695. X.PP
  696. XFinally, the <lang>/<lang>/<filter> form defines a shell command
  697. Xto filter the file with. This can be used to run an arbitrary
  698. Xprogram to filter the contents of a file before it is passed
  699. Xto one of the existing language scanners. It is typically
  700. Xused in conjunction with the plain text scanner.
  701. XThe first <lang> defines a new language, the second <lang>
  702. Xspecifies an existing language whose scanner will be used,
  703. Xand the remaining <filter> is an arbitrary shell command.
  704. X.PP
  705. XYou may get a brief summary of the scanner-specific options for a
  706. Xlanguage by supplying the following option: `-S<language>?'.
  707. X.PP
  708. XHere is a brief summary of the options for the
  709. X.I `asm'\^
  710. X(assembler) language.
  711. X.PP
  712. XThe
  713. X.B \-u\^
  714. Xoption controls whether or not the assembler scanner should strip
  715. Xoff a leading
  716. X.I underscore\^
  717. X(`_') character.  If your assembler prepends an
  718. X.I underscore\^
  719. Xto external symbols, then you should tell the scanner to strip it
  720. Xoff, so that references to the same symbol from assembly and from
  721. Xa high-level language will look the same.
  722. X.PP
  723. XThe
  724. X.B \-c<cc>\^
  725. Xoption supplies the character(s) used to begin a comment that extends
  726. Xto the end of the line.
  727. X.PP
  728. XThe
  729. X.B \-a<cc>\^
  730. Xoption indicates character(s) that are legal in names, in addition to
  731. Xthe alpha-numeric characters.  If the option appears as `-a', names
  732. Xthat contain these characters are ignored.  If it appears as `+a', these
  733. Xnames are added to the database.
  734. X.SH BUGS
  735. XThis manual page needs to be more complete about the scanner-specific
  736. Xarguments.
  737. X.PP
  738. XAt the moment, the only scanners implemented are for C, assembly
  739. Xlanguage, and plain text.  There ought to be scanners for Ada, Pascal,
  740. XFortran, and Lisp.
  741. X.SH SEE ALSO
  742. Xlid(1), deroff(1), detex(1).
  743. END_OF_FILE
  744. if test 5564 -ne `wc -c <'mkid.1'`; then
  745.     echo shar: \"'mkid.1'\" unpacked with wrong size!
  746. fi
  747. # end of 'mkid.1'
  748. fi
  749. if test -f 'paths.c' -a "${1}" != "-c" ; then 
  750.   echo shar: Will not clobber existing file \"'paths.c'\"
  751. else
  752. echo shar: Extracting \"'paths.c'\" \(5284 characters\)
  753. sed "s/^X//" >'paths.c' <<'END_OF_FILE'
  754. X/* Copyright (c) 1986, Greg McGary */
  755. Xstatic char sccsid[] = "@(#)paths.c    1.1 86/10/09";
  756. X
  757. X#include    <bool.h>
  758. X#include    <stdio.h>
  759. X#include    <string.h>
  760. X
  761. Xbool canCrunch();
  762. Xchar *rootName();
  763. Xchar *spanPath();
  764. Xchar *suffName();
  765. Xvoid cannoname();
  766. X
  767. X/* relPath takes two arguments:
  768. X * 1) an absolute path name for a directory.
  769. X *    (This name MUST have a trailing /).
  770. X * 2) an absolute path name for a file.
  771. X *
  772. X * It looks for common components at the front of the file and
  773. X * directory names and generates a relative path name for the file
  774. X * (relative to the specified directory).
  775. X *
  776. X * This may result in a huge number of ../s if the names
  777. X * have no components in common.
  778. X *
  779. X * The output from this concatenated with the input directory name
  780. X * and run through spanPath should result in the original input
  781. X * absolute path name of the file.
  782. X *
  783. X * Examples:
  784. X *  dir      arg                  return value
  785. X *  /x/y/z/  /x/y/q/file      ->  ../q/file
  786. X *  /x/y/z/  /q/t/p/file      ->  ../../../q/t/p/file
  787. X *  /x/y/z/  /x/y/z/file      ->  file
  788. X */
  789. Xchar *
  790. XrelPath(dir, arg)
  791. X    char        *dir;
  792. X    char        *arg;
  793. X{
  794. X    char *        a;
  795. X    char *        d;
  796. X    char *        lasta;
  797. X    char *        lastd;
  798. X    static char    pathBuf[BUFSIZ];
  799. X
  800. X    lasta = a = arg;
  801. X    lastd = d = dir;
  802. X    while (*a == *d) {
  803. X       if (*a == '/') {
  804. X          lasta = a;
  805. X          lastd = d;
  806. X       }
  807. X       ++a;
  808. X       ++d;
  809. X    }
  810. X    /* lasta and lastd now point to the last / in each
  811. X     * file name where the leading file components were
  812. X     * identical.
  813. X     */
  814. X    ++lasta;
  815. X    ++lastd;
  816. X    /* copy a ../ into the buffer for each component of
  817. X     * the directory that remains.
  818. X     */
  819. X    d = pathBuf;
  820. X    while (*lastd != '\0') {
  821. X        if (*lastd == '/') {
  822. X            strcpy(d, "../");
  823. X            d += 3;
  824. X        }
  825. X        ++lastd;
  826. X    }
  827. X    /* now tack on remainder of arg */
  828. X    strcpy(d, lasta);
  829. X    return(pathBuf);
  830. X}
  831. X
  832. X/* spanPath accepts a directory name and a file name and returns
  833. X * a cannonical form of the full file name within that directory.
  834. X * It gets rid of ./ and things like that.
  835. X *
  836. X * If the file is an absolute name then the directory is ignored.
  837. X */
  838. Xchar *
  839. XspanPath(dir, arg)
  840. X    char        *dir;
  841. X    char        *arg;
  842. X{
  843. X    char *          argptr;
  844. X    static char    pathBuf[BUFSIZ];
  845. X
  846. X    /* reduce directory to cannonical form */
  847. X    strcpy(pathBuf, dir);
  848. X    cannoname(pathBuf);
  849. X    /* tack the obilgatory / on the end */
  850. X    strcat(pathBuf, "/");
  851. X    /* stick file name in buffer after directory */
  852. X    argptr = pathBuf + strlen(pathBuf);
  853. X    strcpy(argptr, arg);
  854. X    /* and reduce it to cannonical form also */
  855. X    cannoname(argptr);
  856. X    /* If it is an absolute name, just return it */
  857. X    if (*argptr == '/') return(argptr);
  858. X    /* otherwise, combine the names to cannonical form */
  859. X    cannoname(pathBuf);
  860. X    return(pathBuf);
  861. X}
  862. X
  863. X/* rootName returns the base name of the file with any leading
  864. X * directory information or trailing suffix stripped off. Examples:
  865. X *
  866. X *   /usr/include/stdio.h   ->   stdio
  867. X *   fred                   ->   fred
  868. X *   barney.c               ->   barney
  869. X *   bill/bob               ->   bob
  870. X *   /                      ->   < null string >
  871. X */
  872. Xchar *
  873. XrootName(path)
  874. X    char        *path;
  875. X{
  876. X    static char    pathBuf[BUFSIZ];
  877. X    char        *root;
  878. X    char        *dot;
  879. X
  880. X    if ((root = strrchr(path, '/')) == NULL)
  881. X        root = path;
  882. X    else
  883. X        root++;
  884. X    
  885. X    if ((dot = strrchr(root, '.')) == NULL)
  886. X        strcpy(pathBuf, root);
  887. X    else {
  888. X        strncpy(pathBuf, root, dot - root);
  889. X        pathBuf[dot - root] = '\0';
  890. X    }
  891. X    return pathBuf;
  892. X}
  893. X
  894. X/* suffName returns the suffix (including the dot) or a null string
  895. X * if there is no suffix. Examples:
  896. X *
  897. X *   /usr/include/stdio.h   ->   .h
  898. X *   fred                   ->   < null string >
  899. X *   barney.c               ->   .c
  900. X *   bill/bob               ->   < null string >
  901. X *   /                      ->   < null string >
  902. X */
  903. Xchar *
  904. XsuffName(path)
  905. X    char        *path;
  906. X{
  907. X    char        *dot;
  908. X
  909. X    if ((dot = strrchr(path, '.')) == NULL)
  910. X        return "";
  911. X    return dot;
  912. X}
  913. X
  914. Xbool
  915. XcanCrunch(path1, path2)
  916. X    char        *path1;
  917. X    char        *path2;
  918. X{
  919. X    char        *slash1;
  920. X    char        *slash2;
  921. X
  922. X    slash1 = strrchr(path1, '/');
  923. X    slash2 = strrchr(path2, '/');
  924. X
  925. X    if (slash1 == NULL && slash2 == NULL)
  926. X        return strequ(suffName(path1), suffName(path2));
  927. X    if ((slash1 - path1) != (slash2 - path2))
  928. X        return FALSE;
  929. X    if (!strnequ(path1, path2, slash1 - path1))
  930. X        return FALSE;
  931. X    return strequ(suffName(slash1), suffName(slash2));
  932. X}
  933. X#include    <sys/types.h>
  934. X#include    <sys/stat.h>
  935. X
  936. X/* LookUp adds ../s to the beginning of a file name until it finds
  937. X * the one that really exists. Returns NULL if it gets all the way
  938. X * to / and never finds it.
  939. X *
  940. X * If the file name starts with /, just return it as is.
  941. X *
  942. X * This routine is used to locate the ID database file.
  943. X */
  944. Xchar *
  945. XLookUp(arg)
  946. X    char *        arg;
  947. X{
  948. X    char *        p;
  949. X    static char    pathBuf[BUFSIZ];
  950. X    struct stat    rootb;
  951. X    struct stat    statb;
  952. X
  953. X    /* if we got absolute name, just use it. */
  954. X    if (arg[0] == '/') return(arg);
  955. X    /* if the name we were give exists, don't bother searching */
  956. X    if (stat(arg, &statb) == 0) return(arg);
  957. X    /* search up the tree until we find a directory where this
  958. X     * relative file name is visible.
  959. X     * (or we run out of tree to search by hitting root).
  960. X     */
  961. X    p = pathBuf;
  962. X    if (stat("/", &rootb) != 0) return(NULL);
  963. X    do {
  964. X        strcpy(p, "../");
  965. X        p += 3;
  966. X        strcpy(p, arg);
  967. X        if (stat(pathBuf, &statb) == 0) return(pathBuf);
  968. X        *p = '\0';
  969. X        if (stat(pathBuf, &statb) != 0) return(NULL);
  970. X    } while (! ((statb.st_ino == rootb.st_ino) ||
  971. X                    (statb.st_dev == rootb.st_dev)));
  972. X    return(NULL);
  973. X}
  974. END_OF_FILE
  975. if test 5284 -ne `wc -c <'paths.c'`; then
  976.     echo shar: \"'paths.c'\" unpacked with wrong size!
  977. fi
  978. # end of 'paths.c'
  979. fi
  980. if test -f 'scan-text.c' -a "${1}" != "-c" ; then 
  981.   echo shar: Will not clobber existing file \"'scan-text.c'\"
  982. else
  983. echo shar: Extracting \"'scan-text.c'\" \(4062 characters\)
  984. sed "s/^X//" >'scan-text.c' <<'END_OF_FILE'
  985. X/* Copyright (c) 1986, Greg McGary */
  986. X/* Assembler scanner hacked into a Text scanner by Tom Horsley 1988 */
  987. X
  988. X#include    <bool.h>
  989. X#include    <stdio.h>
  990. X#include    <string.h>
  991. X#include    <ctype.h>
  992. X#include    <id.h>
  993. X
  994. Xchar *getTextId();
  995. Xvoid setTextArgs();
  996. X
  997. Xstatic void clrCtype();
  998. Xstatic void setCtype();
  999. X
  1000. X#define    I1    0x01    /* 1st char of an identifier [a-zA-Z_] */
  1001. X#define    NM    0x02    /* digit [0-9a-fA-FxX] */
  1002. X#define SQ    0x04    /* squeeze these out (.,',-) */
  1003. X#define    EF    0x80    /* EOF */
  1004. X
  1005. X/* Text character classes */
  1006. X#define    ISID1ST(c)    ((rct)[c]&(I1))
  1007. X#define    ISIDREST(c)    ((rct)[c]&(I1|NM|SQ))
  1008. X#define    ISNUMBER(c)    ((rct)[c]&(NM))
  1009. X#define    ISEOF(c)    ((rct)[c]&(EF))
  1010. X#define    ISBORING(c)    (!((rct)[c]&(I1|NM|EF)))
  1011. X#define ISIDSQUEEZE(c)    ((rct)[c]&(SQ))
  1012. X
  1013. Xstatic char idctype[] = {
  1014. X
  1015. X    EF,
  1016. X
  1017. X    /*      0       1       2       3       4       5       6       7   */
  1018. X    /*    -----   -----   -----   -----   -----   -----   -----   ----- */
  1019. X
  1020. X    /*000*/    0,    0,    0,    0,    0,    0,    0,    0,
  1021. X    /*010*/    0,    0,    0,    0,    0,    0,    0,    0,
  1022. X    /*020*/    0,    0,    0,    0,    0,    0,    0,    0,
  1023. X    /*030*/    0,    0,    0,    0,    0,    0,    0,    0,
  1024. X    /*040*/    0,    0,    0,    0,    0,    0,    0,    SQ,
  1025. X    /*050*/    0,    0,    0,    0,    0,    SQ,    SQ,    0,
  1026. X    /*060*/    NM,    NM,    NM,    NM,    NM,    NM,    NM,    NM,    
  1027. X    /*070*/    NM,    NM,    0,    0,    0,    0,    0,    0,
  1028. X    /*100*/    0,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1,
  1029. X    /*110*/    I1,    I1,    I1,    I1,    I1|NM,    I1,    I1,    I1,
  1030. X    /*120*/    I1,    I1,    I1,    I1,    I1,    I1,    I1,    I1,
  1031. X    /*130*/    I1|NM,    I1,    I1,    0,    0,    0,    0,    I1,
  1032. X    /*140*/    0,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1,
  1033. X    /*150*/    I1,    I1,    I1,    I1,    I1|NM,    I1,    I1,    I1,
  1034. X    /*160*/    I1,    I1,    I1,    I1,    I1,    I1,    I1,    I1,
  1035. X    /*170*/    I1|NM,    I1,    I1,    0,    0,    0,    0,    0,
  1036. X
  1037. X    /*200*/    0,    0,    0,    0,    0,    0,    0,    0,
  1038. X    /*210*/    0,    0,    0,    0,    0,    0,    0,    0,
  1039. X    /*220*/    0,    0,    0,    0,    0,    0,    0,    0,
  1040. X    /*230*/    0,    0,    0,    0,    0,    0,    0,    0,
  1041. X    /*240*/    0,    0,    0,    0,    0,    0,    0,    0,
  1042. X    /*250*/    0,    0,    0,    0,    0,    0,    0,    0,
  1043. X    /*260*/    0,    0,    0,    0,    0,    0,    0,    0,
  1044. X    /*270*/    0,    0,    0,    0,    0,    0,    0,    0,
  1045. X    /*300*/    0,    0,    0,    0,    0,    0,    0,    0,
  1046. X    /*310*/    0,    0,    0,    0,    0,    0,    0,    0,
  1047. X    /*320*/    0,    0,    0,    0,    0,    0,    0,    0,
  1048. X    /*330*/    0,    0,    0,    0,    0,    0,    0,    0,
  1049. X    /*340*/    0,    0,    0,    0,    0,    0,    0,    0,
  1050. X    /*350*/    0,    0,    0,    0,    0,    0,    0,    0,
  1051. X    /*360*/    0,    0,    0,    0,    0,    0,    0,    0,
  1052. X    /*370*/    0,    0,    0,    0,    0,    0,    0,    0,
  1053. X
  1054. X};
  1055. X
  1056. X/* 
  1057. X        Grab the next identifier the text source file opened with the
  1058. X    handle `inFILE'.  This state machine is built for speed, not
  1059. X    elegance.
  1060. X*/
  1061. Xchar *
  1062. XgetTextId(inFILE, flagP)
  1063. X    FILE        *inFILE;
  1064. X    int        *flagP;
  1065. X{
  1066. X    static char    idBuf[BUFSIZ];
  1067. X    register char    *rct = &idctype[1];
  1068. X    register int    c;
  1069. X    register char    *id = idBuf;
  1070. X
  1071. Xtop:
  1072. X    c = getc(inFILE);
  1073. X    while (ISBORING(c))
  1074. X        c = getc(inFILE);
  1075. X    if (ISEOF(c)) {
  1076. X        return NULL;
  1077. X    }
  1078. X    id = idBuf;
  1079. X    *id++ = c;
  1080. X    if (ISID1ST(c)) {
  1081. X        *flagP = IDN_NAME;
  1082. X        while (ISIDREST(c = getc(inFILE)))
  1083. X            if (! ISIDSQUEEZE(c)) *id++ = c;
  1084. X    } else if (ISNUMBER(c)) {
  1085. X        *flagP = IDN_NUMBER;
  1086. X        while (ISNUMBER(c = getc(inFILE)))
  1087. X            *id++ = c;
  1088. X    } else {
  1089. X        if (isprint(c))
  1090. X            fprintf(stderr, "junk: `%c'", c);
  1091. X        else
  1092. X            fprintf(stderr, "junk: `\\%03o'", c);
  1093. X        goto top;
  1094. X    }
  1095. X
  1096. X    *id = '\0';
  1097. X    ungetc(c, inFILE);
  1098. X    *flagP |= IDN_LITERAL;
  1099. X    return idBuf;
  1100. X}
  1101. X
  1102. Xstatic void
  1103. XsetCtype(chars, type)
  1104. X    char        *chars;
  1105. X    int        type;
  1106. X{
  1107. X    char        *rct = &idctype[1];
  1108. X
  1109. X    while (*chars)
  1110. X        rct[*chars++] |= type;
  1111. X}
  1112. Xstatic void
  1113. XclrCtype(chars, type)
  1114. X    char        *chars;
  1115. X    int        type;
  1116. X{
  1117. X    char        *rct = &idctype[1];
  1118. X
  1119. X    while (*chars)
  1120. X        rct[*chars++] &= ~type;
  1121. X}
  1122. X
  1123. Xextern char    *MyName;
  1124. Xstatic void
  1125. Xusage(lang)
  1126. X    char        *lang;
  1127. X{
  1128. X    fprintf(stderr, "Usage: %s -S%s([(+|-)a<cc>] [(+|-)s<cc>]\n", MyName, lang);
  1129. X    exit(1);
  1130. X}
  1131. Xstatic char *textDocument[] =
  1132. X{
  1133. X"The Text scanner arguments take the form -Stext<arg>, where",
  1134. X"<arg> is one of the following: (<cc> denotes one or more characters)",
  1135. X"  (+|-)a<cc> . . Include (or exculde) <cc> in ids.",
  1136. X"  (+|-)s<cc> . . Squeeze (or don't squeeze) <cc> out of ids.",
  1137. XNULL
  1138. X};
  1139. Xvoid
  1140. XsetTextArgs(lang, op, arg)
  1141. X    char        *lang;
  1142. X    int        op;
  1143. X    char        *arg;
  1144. X{
  1145. X    if (op == '?') {
  1146. X        document(textDocument);
  1147. X        return;
  1148. X    }
  1149. X    switch (*arg++)
  1150. X    {
  1151. X    case 'a':
  1152. X        if (op == '+') {
  1153. X            setCtype(arg, I1) ;
  1154. X        } else {
  1155. X            clrCtype(arg, I1) ;
  1156. X        }
  1157. X        break;
  1158. X    case 's':
  1159. X        if (op == '+') {
  1160. X            setCtype(arg, SQ) ;
  1161. X        } else {
  1162. X            clrCtype(arg, SQ) ;
  1163. X        }
  1164. X        break;
  1165. X    default:
  1166. X        if (lang)
  1167. X            usage(lang);
  1168. X        break;
  1169. X    }
  1170. X}
  1171. END_OF_FILE
  1172. if test 4062 -ne `wc -c <'scan-text.c'`; then
  1173.     echo shar: \"'scan-text.c'\" unpacked with wrong size!
  1174. fi
  1175. # end of 'scan-text.c'
  1176. fi
  1177. if test -f 'symfunc.el' -a "${1}" != "-c" ; then 
  1178.   echo shar: Will not clobber existing file \"'symfunc.el'\"
  1179. else
  1180. echo shar: Extracting \"'symfunc.el'\" \(3162 characters\)
  1181. sed "s/^X//" >'symfunc.el' <<'END_OF_FILE'
  1182. X;; This file provides functions for symbols, that is, things consisting only
  1183. X;; of characters matching the regular expression \(\w\|\s_\).  The functions
  1184. X;; are similar to those provided for words (e.g., symbol-around-point is
  1185. X;; just like word-around-point).
  1186. X
  1187. X(provide 'symfunc)
  1188. X
  1189. X(defvar symbol-char-re "\\(\\w\\|\\s_\\)"
  1190. X"The regular expression that matches a character belonging to a symbol.")
  1191. X
  1192. X(defun symbol-around-point ()
  1193. X  "return the symbol around the point as a string"
  1194. X  (save-excursion
  1195. X    (let (beg)
  1196. X      (if (not (at-beginning-of-symbol))
  1197. X      (forward-symbol -1))
  1198. X      (setq beg (point))
  1199. X      (forward-symbol 1)
  1200. X      (buffer-substring beg (point))
  1201. X    )
  1202. X  )
  1203. X)
  1204. X
  1205. X(defun at-beginning-of-symbol ()
  1206. X"Return t if point is currently positioned at the beginning of
  1207. Xa symbol."
  1208. X   (and
  1209. X      (looking-at symbol-char-re)
  1210. X      (not (looking-back symbol-char-re))
  1211. X   )
  1212. X)
  1213. X
  1214. X(defun forward-symbol (arg)
  1215. X"Move point forward ARG symbols (backward if ARG is negative).
  1216. XNormally returns t.
  1217. XIf an edge of the buffer is reached, point is left there
  1218. Xand nil is returned.
  1219. XIt is faster to call backward-symbol than to call forward-symbol
  1220. Xwith a negative argument."
  1221. X   (interactive "p")
  1222. X   (if (null arg)
  1223. X      (setq arg 1)
  1224. X   )
  1225. X   (if (< arg 0)
  1226. X      (backward-symbol (- arg))
  1227. X      (progn
  1228. X         (while (> arg 0)
  1229. X            (condition-case ()
  1230. X               (progn
  1231. X                  (while (not (looking-at symbol-char-re))
  1232. X                     (forward-char 1)
  1233. X                  )
  1234. X                  (while (looking-at symbol-char-re)
  1235. X                     (forward-char 1)
  1236. X                  )
  1237. X                  t
  1238. X               )
  1239. X               (error nil)          ;; Return nil if error
  1240. X            )
  1241. X            (setq arg (1- arg))
  1242. X         )
  1243. X      )
  1244. X   )
  1245. X)
  1246. X
  1247. X(defun backward-symbol (arg)
  1248. X"Move backward until encountering the end of a symbol.
  1249. XWith argument, do this that many times.
  1250. XIn programs, it is faster to call forward-symbol
  1251. Xthan to call backward-symbol with a negative arg."
  1252. X   (interactive "p")
  1253. X   (if (null arg)
  1254. X      (setq arg 1)
  1255. X   )
  1256. X   (if (< arg 0)
  1257. X      (forward-symbol (- arg))
  1258. X      (progn
  1259. X         (while (> arg 0)
  1260. X            (condition-case ()
  1261. X               (progn
  1262. X                  (while (not (looking-back symbol-char-re))
  1263. X                     (forward-char -1)
  1264. X                  )
  1265. X                  (while (looking-back symbol-char-re)
  1266. X                     (forward-char -1)
  1267. X                  )
  1268. X                  t
  1269. X               )
  1270. X               (error nil)          ;; Return nil if error
  1271. X            )
  1272. X            (setq arg (1- arg))
  1273. X         )
  1274. X      )
  1275. X   )
  1276. X)
  1277. X
  1278. X;; Additional word-oriented functions.
  1279. X
  1280. X(defun word-around-point ()
  1281. X  "return the word around the point as a string"
  1282. X  (save-excursion
  1283. X    (let (beg)
  1284. X      (if (not (looking-at "\\<"))
  1285. X      (forward-word -1))
  1286. X      (setq beg (point))
  1287. X      (forward-word 1)
  1288. X      (buffer-substring beg (point)))))
  1289. X
  1290. X;; The looking-back function used to exist in Emacs distribution, but
  1291. X;; it disappeared in 18.52.
  1292. X
  1293. X(defun looking-back (str)
  1294. X  "returns t if looking back reg-exp STR before point."
  1295. X  (and
  1296. X     (save-excursion (re-search-backward str nil t))
  1297. X     (= (point) (match-end 0))
  1298. X  )
  1299. X)
  1300. END_OF_FILE
  1301. if test 3162 -ne `wc -c <'symfunc.el'`; then
  1302.     echo shar: \"'symfunc.el'\" unpacked with wrong size!
  1303. fi
  1304. # end of 'symfunc.el'
  1305. fi
  1306. if test -f 'unsymlink.c' -a "${1}" != "-c" ; then 
  1307.   echo shar: Will not clobber existing file \"'unsymlink.c'\"
  1308. else
  1309. echo shar: Extracting \"'unsymlink.c'\" \(2622 characters\)
  1310. sed "s/^X//" >'unsymlink.c' <<'END_OF_FILE'
  1311. X#include <string.h>
  1312. X#include <sys/param.h>
  1313. X#include <sys/stat.h>
  1314. X
  1315. Xextern void cannoname();
  1316. X
  1317. X/* unsymlink is a routine that resolves all symbolic links in
  1318. X * a file name, transforming a name to the "actual" file name
  1319. X * instead of the name in terms of symbolic links.
  1320. X *
  1321. X * If it can resolve all links and discover an actual file
  1322. X * it returns a pointer to its argument string and transforms
  1323. X * the argument in place to the actual name.
  1324. X *
  1325. X * If no such actual file exists, or for some reason the links
  1326. X * cannot be resolved, it returns a NULL pointer and leaves the
  1327. X * name alone.
  1328. X */
  1329. Xchar *
  1330. Xunsymlink(n)
  1331. X   char *    n;
  1332. X{
  1333. X   char          newname[MAXPATHLEN];
  1334. X   char          partname[MAXPATHLEN];
  1335. X   char          linkname[MAXPATHLEN];
  1336. X   char *        s;
  1337. X   char *        d;
  1338. X   char *        lastcomp;
  1339. X   int           linksize;
  1340. X   struct stat   statb;
  1341. X
  1342. X   /* Just stat the file to automagically do all the symbolic
  1343. X    * link verification checks and make sure we have access to
  1344. X    * directories, etc.
  1345. X    */
  1346. X   if (stat(n, &statb) != 0) return(NULL) ;
  1347. X   strcpy(newname, n);
  1348. X   /* Now loop, lstating each component to see if it is a symbolic
  1349. X    * link. For symbolic link components, use readlink() to get
  1350. X    * the real name, put the read link name in place of the
  1351. X    * last component, and start again.
  1352. X    */
  1353. X   cannoname(newname) ;
  1354. X   s = &newname[0] ;
  1355. X   d = &partname[0] ;
  1356. X   if (*s == '/') {
  1357. X      *d++ = *s++ ;
  1358. X   }
  1359. X   lastcomp = d ;
  1360. X   for ( ; ; ) {
  1361. X      if ((*s == '/') || (*s == '\0')) {
  1362. X         /* we have a complete component name in partname, check it out */
  1363. X         *d = '\0' ;
  1364. X         if (lstat(partname, &statb) != 0) return(NULL) ;
  1365. X         if ((statb.st_mode & S_IFMT) == S_IFLNK) {
  1366. X            /* This much of name is a symbolic link, do a readlink
  1367. X             * and tack the bits and pieces together
  1368. X             */
  1369. X            linksize = readlink(partname, linkname, MAXPATHLEN) ;
  1370. X            if (linksize < 0) return(NULL) ;
  1371. X            linkname[linksize] = '\0' ;
  1372. X            strcpy(lastcomp, linkname) ;
  1373. X            lastcomp += linksize ;
  1374. X            strcpy(lastcomp, s) ;
  1375. X            strcpy(newname, partname) ;
  1376. X            cannoname(newname) ;
  1377. X            s = &newname[0] ;
  1378. X            d = &partname[0] ;
  1379. X            if (*s == '/') {
  1380. X               *d++ = *s++ ;
  1381. X            }
  1382. X            lastcomp = d ;
  1383. X         } else {
  1384. X            /* Not a symlink, just keep scanning to next component */
  1385. X            if (*s == '\0') break ;
  1386. X            *d++ = *s++ ;
  1387. X            lastcomp = d ;
  1388. X         }
  1389. X      } else {
  1390. X         *d++ = *s++ ;
  1391. X      }
  1392. X   }
  1393. X   strcpy(n, newname) ;
  1394. X   return(n) ;
  1395. X}
  1396. END_OF_FILE
  1397. if test 2622 -ne `wc -c <'unsymlink.c'`; then
  1398.     echo shar: \"'unsymlink.c'\" unpacked with wrong size!
  1399. fi
  1400. # end of 'unsymlink.c'
  1401. fi
  1402. echo shar: End of archive 2 \(of 7\).
  1403. cp /dev/null ark2isdone
  1404. MISSING=""
  1405. for I in 1 2 3 4 5 6 7 ; do
  1406.     if test ! -f ark${I}isdone ; then
  1407.     MISSING="${MISSING} ${I}"
  1408.     fi
  1409. done
  1410. if test "${MISSING}" = "" ; then
  1411.     echo You have unpacked all 7 archives.
  1412.     rm -f ark[1-9]isdone
  1413. else
  1414.     echo You still need to unpack the following archives:
  1415.     echo "        " ${MISSING}
  1416. fi
  1417. ##  End of shell archive.
  1418. exit 0
  1419.  
  1420. exit 0 # Just in case...
  1421.